import {ChangeDetectorRef, Component, forwardRef, Inject, Input, OnInit, ViewChild} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {SysCodeCategoryService} from '../service/sys-code-category.service';
import {NzFormatEmitEvent, NzMessageService, NzTreeSelectComponent} from 'ng-zorro-antd';
import {Observable, Subject, timer} from 'rxjs';


@Component({
    selector: 'sys-code-category-select',
    templateUrl: './sys-code-category-select.component.html',
    styleUrls: ['./sys-code-category-select.component.less'],
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => SysCodeCategorySelectComponent),
            multi: true
        }
    ]
})
export class SysCodeCategorySelectComponent implements OnInit, ControlValueAccessor {

    @ViewChild('nzTree', {static: true})
    nzTree: NzTreeSelectComponent;

    categoryValues = [];

    nzDropdownStyle = {
        width: '300px',
        'overflow-x': 'hidden',
        'min-height': '200px'
    };

    @Input()
    valueChange: (value: string | string[] | object) => any;
    changeFn = undefined;
    disabled = false;

    constructor(protected sysCodeCategoryService: SysCodeCategoryService,
                protected message: NzMessageService,
                @Inject(ChangeDetectorRef) public readonly cd: ChangeDetectorRef) {
    }

    _value;

    get value() {
        return this._value;
    }

    set value(value: any) {
        this._value = value;
        if (this.changeFn) {
            this.changeFn(value);
        }
        if (this.valueChange) {
            this.valueChange(value);
        }
    }

    ngOnInit(): void {
        this.updateCodes();
    }

    updateCodes() {
        this.sysCodeCategoryService.getComboBoxNzTree('-1').subscribe(returnForm => {
            if (returnForm.success) {
                this.categoryValues = returnForm.message;
                this.cd.detectChanges();
            } else {
                this.message.error('加载节点数据异常：' + returnForm.errorMessage);
            }
        });
    }

    reloadNode(nodeId): Observable<any> {
        const node = this.nzTree.getTreeNodeByKey(nodeId);
        if (node) {
            node.isLeaf = false;
            node.isExpanded = true;
        }
        const subject = new Subject();
        this.sysCodeCategoryService.getComboBoxNzTree(nodeId).subscribe(returnForm => {
            if (returnForm.success) {
                node.clearChildren();
                node.addChildren(returnForm.message);
                node.isLeaf = returnForm.message.length === 0;
                node.isExpanded = true;

                timer(200).subscribe(() => {
                    for (const one of returnForm.message) {
                        if (one.expanded && !one.isLeaf) {
                            const c = this.nzTree.getTreeNodeByKey(one.key);
                            if (c.children.length === 0) {
                                this.reloadNode(one.key);
                            }
                        }
                    }
                });
            } else {
                this.message.error('加载节点数据异常：' + returnForm.errorMessage);
            }
            timer(100).subscribe(() => {
                subject.next(returnForm);
                subject.complete();
            });
        });
        return subject;
    }

    onExpandChange(e: NzFormatEmitEvent) {
        const node = e.node;
        if (node && node.getChildren().length === 0 && node.isExpanded) {
            this.reloadNode(node.key);
        }
    }

    registerOnChange(fn: any): void {
        this.changeFn = fn;
    }

    registerOnTouched(fn: any): void {
    }

    setDisabledState(isDisabled: boolean): void {
        this.disabled = isDisabled;
    }

    writeValue(_value: any): void {
        if (_value) {
            const node = this.nzTree.getTreeNodeByKey(_value);
            if (!node) {
                timer(100).subscribe(() => {
                    this.sysCodeCategoryService.getTreeNodeCodePath(_value).subscribe(res => {
                        if (res.success) {
                            const parentPath: string[] = res.message || [];
                            parentPath.push(_value);
                            this.reloadNodeByPath(parentPath);
                        }
                    });
                });
                return;
            }
        }
        this._value = _value;
        this.cd.detectChanges();
    }

    reloadNodeByPath(paths: string[]) {
        const path = paths.shift();
        const node = this.nzTree.getTreeNodeByKey(path);
        if (paths.length !== 0) {
            if (node != null) {
                if (node.getChildren().length === 0) {
                    this.reloadNode(node.key).subscribe(returnForm => {
                        this.reloadNodeByPath(paths);
                    });
                } else {
                    node.isExpanded = true;
                    this.reloadNodeByPath(paths);
                }
            } else {
                this.message.error('节点加载异常 , 异常节点Id为 ' + path);
            }
        } else {
            this._value = path;
            this.cd.detectChanges();
        }
    }
}
